--
-- Funcion de control de movimientos desde la base de datos
-- Esquema de función y trigger que permite agrupar en un lugar las caracteristicas propias de un cliente
-- para no crear multiples triggers particulares. 
--

CREATE OR REPLACE FUNCTION cliente.__movs_control(
	ptipomov character varying,
	poperacion character varying,
	pidmov integer)
    RETURNS character varying
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
AS $BODY$
DECLARE
BEGIN
  -- Esta funcion se customiza en el cliente, es para casos especiales. Si devuelve un valor diferente a cadena vacia
  -- se levantara una excepcion
  /* Los valores de pTipoMov pueden ser cualquiera, hay que ver el trigger que lo llame.
     Al momento de crear la función solo valen ART,CON, CTB Y CTE.
     Los valores de operacion pueden ser los determinados por postgres 
	 'DELETE', 'UPDATE' (el INSERT no tiene sentido porque no obtendríamos nada con un Id solamente)
     La funcion se dispara a traves de la funcion de trigger 
     public.tg_movs_control_cliente(<TipoMov>)
	 (ej. public.tg_movs_control_cliente('ART') )
	 la operacion y el ID los envia esta funcion 
  */
  RETURN '';
END;
$BODY$;

ALTER FUNCTION cliente.__movs_control(character varying, character varying, integer)
    OWNER TO abacouser;

GRANT EXECUTE ON FUNCTION cliente.__movs_control(character varying, character varying, integer) TO PUBLIC;

GRANT EXECUTE ON FUNCTION cliente.__movs_control(character varying, character varying, integer) TO abacouser;

COMMENT ON FUNCTION cliente.__movs_control(character varying, character varying, integer)
    IS 'Funcion llamada desde funcion de trigger tg_movs_control_cliente para validar una operacion de delete-update de un MOV';

---
---
---

CREATE OR REPLACE FUNCTION public.tg_movs_control_cliente()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
--
-- Funcion para trigger de after delete sobre artm llama a una función de cliente con el idartm que se está borrando
-- para que la función decida que hacer, por defecto devuelve una cadena vacia, si la cadena no es vacia esta
-- funcion levanta un error
--
DECLARE
  vMensajeExcepcion varchar;
  vId  INTEGER;
BEGIN
  IF TG_OP IN ('DELETE') THEN
     vId := old.id;
  ELSE
     vId := new.id;
  END IF;
  
  vMensajeExcepcion := (SELECT cliente.__movs_control(TG_ARGV[0], TG_OP, vId));

  IF vMensajeExcepcion <> '' THEN 
     RAISE EXCEPTION '%', vMensajeExcepcion;
  END IF;
  
  IF TG_OP IN ('DELETE') THEN
     RETURN OLD;
  ELSE
     RETURN NEW;
  END IF;

END;
$BODY$;

ALTER FUNCTION public.tg_movs_control_cliente()
    OWNER TO abacouser;

GRANT EXECUTE ON FUNCTION public.tg_movs_control_cliente() TO PUBLIC;

GRANT EXECUTE ON FUNCTION public.tg_movs_control_cliente() TO abacouser;

COMMENT ON FUNCTION public.tg_movs_control_cliente()
    IS 'Funcion del trigger que llama a la funcion cliente.__movs_control(...) que analizara si se puede borrar o modificar o insertar o no';


CREATE TRIGGER artm_000_control_cliente
    BEFORE DELETE OR UPDATE 
    ON public.artm
    FOR EACH ROW
    EXECUTE PROCEDURE public.tg_movs_control_cliente('ART');

CREATE TRIGGER conm_000_control_cliente
    BEFORE DELETE OR UPDATE
    ON public.conm
    FOR EACH ROW
    EXECUTE PROCEDURE public.tg_movs_control_cliente('CON');

CREATE TRIGGER ctbm_000_control_cliente
    BEFORE DELETE OR UPDATE
    ON public.ctbm
    FOR EACH ROW
    EXECUTE PROCEDURE public.tg_movs_control_cliente('CTB');

CREATE TRIGGER ctem_000_control_cliente
    BEFORE DELETE OR UPDATE 
    ON public.ctem
    FOR EACH ROW
    EXECUTE PROCEDURE public.tg_movs_control_cliente('CTE');



--    
SELECT aaversion('510.00','509.06');
--    


